#ifndef __M_CONFIG_H__
#define __M_CONFIG_H__

#include <stdint.h>

#include "file.h"

#define SETTING_CONFIG_VERSION 1
#define GRAPHICS_CONFIG_VERSION 1
#define CONTROL_CONFIG_VERSION 1
#define CORE_CONFIG_VERSION 1
#define MISC_CONFIG_VERSION 1

#define SETTING_CONFIG_NAME "setting.cfg"
#define GRAPHICS_CONFIG_NAME "graphics.cfg"
#define CONTROL_CONFIG_NAME "control.cfg"
#define CORE_CONFIG_NAME "core.cfg"
#define MISC_CONFIG_NAME "misc.cfg"

#define OVERLAYS_DIR_NAME "overlays"
#define PREVIEW_DIR_NAME "images"

#define CORE_ASSETS_DIR_NAME "assets"
#define CORE_SYSTEM_DIR_NAME "system"

#define FONT_PGF_NAME "font.pgf"
#define WALLPAPER_PNG_NAME "bg.png"
#define SPLASH_PNG_NAME "splash.png"

#define APP_DATA_DIR "ux0:data/EMU4VITA/" APP_DIR_NAME
#define APP_ASSETS_DIR "app0:assets"
#define CORE_DATA_DIR "app0:data"

#define CORE_CONFIGS_DIR APP_DATA_DIR "/configs"
#define CORE_SAVEFILES_DIR APP_DATA_DIR "/savefiles"
#define CORE_SAVESTATES_DIR APP_DATA_DIR "/savestates"
#define CORE_SCREENSHOTS_DIR APP_DATA_DIR "/screenshots"

#define APP_LOG_PATH APP_DATA_DIR "/log.txt"
#define CORE_LOG_PATH APP_DATA_DIR "/core_log.txt"
#define LASTFILE_PATH APP_DATA_DIR "/lastfile.txt"

#define MAX_CONFIG_NAME_LENGTH 128
#define MAX_CONFIG_STRING_LENGTH 1024
#define MAX_CONFIG_LINE_LENGTH 2048

#define ENABLE_BUTTON_MASK (1 << 31)
#define TURBO_BUTTON_MASK (1 << 30)
#define RETRO_KEY_BITMASK(id) (1 << id)

#define SET_BUTTON(id) ((1 << id) | ENABLE_BUTTON_MASK)
#define SET_BUTTON_WITH_TURBO(id) ((1 << id) | ENABLE_BUTTON_MASK | TURBO_BUTTON_MASK)

#define EXIT_APP_HOT_KEY (SCE_CTRL_PSBUTTON | SCE_CTRL_SELECT)
#define CHECK_EXIT_APP(key) ((key & EXIT_APP_HOT_KEY) == EXIT_APP_HOT_KEY)

#define SKIP_PRESSED_PSBUTTON_COUNT 20
#define ENALBE_HOLD_BUTTON_COUNT 20

enum EmuScreenSize
{
    EMU_SCREEN_SIZE_1X,
    EMU_SCREEN_SIZE_2X,
    EMU_SCREEN_SIZE_3X,
    EMU_SCREEN_SIZE_FIT,
    EMU_SCREEN_SIZE_FIT_8_7,
    EMU_SCREEN_SIZE_FIT_4_3,
    EMU_SCREEN_SIZE_FIT_3_2,
    EMU_SCREEN_SIZE_FULL,
};

enum PreviewStyle
{
    PREVIEW_PRESERVE_FILL,
    PREVIEW_FULL_FILL,
};

enum ConfigType
{
    CONFIG_TYPE_MAIN,
    CONFIG_TYPE_GAME,
};

typedef struct
{
    uint32_t version;        // 0x00
    uint32_t preview_path;   // 0x04
    uint32_t preview_style;  // 0x08
    uint32_t app_log;        // 0x0C
    uint32_t core_log;       // 0x10
    uint32_t loading_log;    // 0x14
    char reserved[0x50];     // 0x18
} SettingConfig;             // 0x68

typedef struct
{
    uint32_t version;            // 0x00
    uint32_t graphics_filtering; // 0x04
    uint32_t smooth_graphics;    // 0x08
    uint32_t show_overlay;       // 0x0C
    uint32_t show_fps;           // 0x10
    uint32_t screen_size;        // 0x14
    uint32_t reserved0;          // 0x18
    uint32_t display_rotate;     // 0x1C
    char reserved[0x48];         // 0x20
} GraphicsConfig;                // 0x68

typedef struct
{
    uint32_t version;         // 0x00
    uint32_t button_up;       // 0x04
    uint32_t button_down;     // 0x08
    uint32_t button_left;     // 0x0C
    uint32_t button_right;    // 0x10
    uint32_t button_triangle; // 0x14
    uint32_t button_circle;   // 0x18
    uint32_t button_cross;    // 0x1C
    uint32_t button_square;   // 0x20
    uint32_t button_select;   // 0x24
    uint32_t button_start;    // 0x28
    uint32_t button_l;        // 0x2C
    uint32_t button_r;        // 0x30
    uint32_t button_l2;       // 0x34
    uint32_t button_r2;       // 0x38
    uint32_t button_l3;       // 0x3C
    uint32_t button_r3;       // 0x40
    uint32_t left_analog;     // 0x44
    uint32_t right_analog;    // 0x48
    uint32_t front_touch_pad; // 0x4C
    uint32_t back_touch_pad;  // 0x50
    uint32_t turbo_delay;     // 0x54
    char reserved[0x28];      // 0x58
} ControlConfig;              // 0x80

typedef struct
{
    uint32_t version;          // 0x00
    uint32_t auto_save_load;   // 0x04
    uint32_t reserved0;        // 0x08
    uint32_t reserved1;        // 0x0C
    uint32_t reserved2;        // 0x10
    char reserved[0x54];       // 0x14
} MiscConfig;                  // 0x68

void initConfigs();

void trimString(char *str);
char *trimStringEx(char *str);

int configGetDecimal(const char *str);
int configGetHexdecimal(const char *str);
int configGetBoolean(const char *str);
char *configGetString(const char *str);

int configGetLine(const char *buf, int size, char **line);
int configReadLine(const char *line, char **name, char **string);

int setDefaultSettingConfig();
int setDefaultGraphicsConfig();
int setDefaultControlConfig();
#if defined(WSC_BUILD)
int setDefaultControlConfigV();
#endif
int setDefaultCoreConfig();
int setDefaultMiscConfig();

int loadSettingConfig(int type);
int loadGraphicsConfig(int type);
int loadControlConfig(int type);
int loadCoreConfig(int type);
int loadMiscConfig(int type);

int saveSettingConfig(int type);
int saveGraphicsConfig(int type);
int saveControlConfig(int type);
int saveCoreConfig(int type);
int saveMiscConfig(int type);

extern SettingConfig setting_config;
extern GraphicsConfig graphics_config;
extern ControlConfig control_config;
extern MiscConfig misc_config;

extern char *private_assets_dir;
extern char *public_assets_dir;

extern unsigned user_language;

#endif
